﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Text.RegularExpressions;

namespace CATcpClientSender
{
    public class HenuTcpSender
    {


        public static void SendPackage()
        {
            TcpClient tcp = new TcpClient();
            //bool loop = true;
            //while (loop)
            //{
            //    Console.WriteLine("Next----");
            //    string commond = Console.ReadLine().Trim();
            //    if (string.IsNullOrEmpty(commond))
            //    {
            //        Console.WriteLine("Press any key to end");

            //        Console.ReadLine();
            //        loop = false;
            //    }
            //    else
            //    {
            //        if (!bool.TryParse(commond, out loop))
            //        {
            //            if (commond.ToUpper() == "Y")
            //                loop = true;
            //            else
            //                loop = false;
            //        }

            //    }

            //}



            Console.WriteLine("Establishing Connection to Host");
            IAsyncResult ar = tcp.BeginConnect(IPAddress.Parse("127.0.0.1"), 60000, InvokeCallback, tcp);
            // Wait here until the callback processes the connection.
            ar.AsyncWaitHandle.WaitOne();

            Console.ReadLine();

        }
        /// <summary>
        /// 连接完成的回调
        /// </summary>
        /// <param name="ar"></param>
        private static void InvokeCallback(IAsyncResult ar)
        {
            // 无线车次号
            string line = "0D D4 25 9F 0C 2B 00 3F 1F 00 00 1F 8C 30 20 03 03 03 20 20 20 54 05 0D 00 01 00 39 30 8E E8 61 96 00 00 39 30 64 00 0C 01 00 01 01 39 30 00 99 3B 00";
            // 心跳数据包
            line += "42 48 45 58 58 58 58 58 38 42 35 30 33 38 30 10 c5 46 78 89";
            // 心跳数据包
            line += "42 48 45 58 58 58 58 58 38 42 35 30 33 38 30 10 c5 46 78 89";

            line += "24 54 58 58 58 00 63 02 16 AC 60 02 16 AF 00 00 02 74 A4 24 47 50 47 47 41 2C 30 31 35 32 30 34 2E 30 30 2C 33 34 34 38 2E 36 30 33 35 31 33 33 33 2C 4E 2C 31 31 33 33 33 2E 31 39 32 33 35 30 36 30 2C 45 2C 32 2C 30 35 2C 35 2E 34 2C 31 31 39 2E 38 34 33 2C 4D 2C 2D 31 36 2E 32 34 37 2C 46 00 91";
            line += "24 47 50 47 47 41 2C 30 31 35 32 30 34 2E 30 30 2C 33 34 34 38 2E 36 30 33 35 31 33 33 33 2C 4E 2C 31 31 33 33 33 2E 31 39 32 33 35 30 36 30 2C 45 2C 32 2C 30 35 2C 35 2E 34 2C 31 31 39 2E 38 34 33 2C 4D 2C 2D 31 36 2E 32 34 37 2C 46";
            // 无线车次数据
            line += "24 54 58 58 58 00 47 02 16 AC 60 02 16 AF 00 00 01 98 A4 0D D4 25 9F 0C 2B 00 3F 1F 00 00 1F 8C 30 20 02 02 03 20 20 20 54 B8 22 00 01 00 39 30 00 09 3D 64 00 00 39 30 64 00 0C 01 00 01 01 39 30 00 33 58 00 00 61";

            // 心跳数据包
            line += "42 48 45 58 58 58 58 58 38 42 35 30 33 38 30 10 c5 46 78 89";

            MatchCollection dexMatch = Regex.Matches(line, @"([0-9a-fA-Fa-f]{2})");

            byte[] data = new byte[dexMatch.Count];
            for (int i = 0; i < dexMatch.Count; i++)
            {
                data[i] = Convert.ToByte(dexMatch[i].Value, 16);
            }

            string snodata = Encoding.Default.GetString(data);

            byte xf = (byte)'*';
            //SendSerialPort(data);

            //byte[] userId = new byte[3];
            //Array.Copy(data, 7, userId, 0, 3);
            //string userAddress = Convert.ToString(userId[0], 16) + Convert.ToString(userId[1], 16) + Convert.ToString(userId[2], 16);
            //int value = Convert.ToInt32(userAddress, 16);
            ////long valeu = BitConverter.ToInt64(userId,0);
            //string sno = Encoding.Default.GetString(userId);

            byte[] gdata = Encoding.Default.GetBytes("$GPGGA,066933.40,3446.58817811,N,11337.38856450,E,2,22,0.6,106.926,M,-16.011,M,3.4,0129*6B");

            #region CRC校验
            //byte df = (byte)'$';
            //byte xf = (byte)'*';
            //byte GF = (byte)'G';

            //byte contentLenH = data[5];
            //byte contenLenL = data[6];
            //ushort len = (ushort)(contentLenH * 256 + contenLenL);

            //byte[] content = new byte[len - 19 - 2];
            //// 长度 = 包头(19位) +  封装报文内容 （可变） + CRC标志(1) + 校验和(1)
            //Array.Copy(data, 19, content, 0, content.Length);

            //byte? crcSum = GetSum(data, 19 - 2, data.Length - 19 - 1);


            //byte sCRC = data[50 - 2];
            //byte lCRC = data[50 - 1];

            //ushort revSum = (ushort)(sCRC * 256 + lCRC);

            //ushort cvalue = CRC16_cala(data.ToList(), 4, 50 - 6);
            #endregion

            TcpClient client = ar.AsyncState as TcpClient;

            List<byte[]> senList = new List<byte[]>();
            senList.Add(data);
            senList.Add(gdata);
            senList.Add(gdata);
            senList.Add(gdata);
            senList.Add(gdata);
            senList.Add(gdata);
            senList.Add(gdata);
            senList.Add(gdata);
            senList.Add(gdata);


            if (client.Connected)
            {
                NetworkStream stream = client.GetStream();
                bool flgNext = true;
                while (flgNext)
                {
                    foreach (var item in senList)
                    {
                        string message = Encoding.Default.GetString(item);
                        Console.WriteLine("Send:->" + message);
                        stream.Write(item, 0, item.Length);
                    }
                    Console.WriteLine("Please enter 'Y' to make a Next loop.");
                    string msl = Console.ReadLine().Trim();
                    if (msl.ToUpper() != "Y")
                        flgNext = false;
                }
                SendSerialPort(data);
                client.EndConnect(ar);
            }

            

        }
        /// <summary>
        /// 异或校验
        /// </summary>
        /// <param name="array"></param>
        /// <param name="startIndex"></param>
        /// <param name="len"></param>
        /// <returns></returns>
        public static byte? GetSum(byte[] array, int startIndex, int len)
        {
            if (array.Length - startIndex > len)
            {
                byte sum = 0;
                for (int i = 0; i < len; i++)
                {
                    sum ^= array[startIndex + i];
                }
                return sum;
            }
            else
                return null;
        }

        #region  CRC16校验
        /// <summary>
        /// 校验表
        /// </summary>
        static uint[] crc_table = { 0x0000u, 0x1021u, 0x2042u, 0x3063u, 0x4084u, 0x50a5u, 0x60c6u, 0x70e7u, 0x8108u, 0x9129u, 0xa14au, 0xb16bu, 0xc18cu, 0xd1adu, 0xe1ceu, 0xf1efu };
        /// <summary>
        /// CRC校验
        /// </summary>
        /// <param name="ptr"></param>
        /// <param name="startIndex"></param>
        /// <param name="data_length"></param>
        /// <returns></returns>
        static ushort CRC16_cala(List<byte> ptr, int startIndex, int data_length)
        {
            ushort crc = 0;
            byte crc_H4;
            int i = startIndex;
            while (data_length != 0)
            {
                data_length = data_length - 1;
                crc_H4 = (byte)(crc >> 12);
                crc = (ushort)(crc << 4);
                crc = (ushort)(crc ^ crc_table[crc_H4 ^ (ptr[i] >> 4)]);
                crc_H4 = (byte)(crc >> 12);
                crc = (ushort)(crc << 4);
                crc = (ushort)(crc ^ crc_table[crc_H4 ^ (ptr[i] & 0x0f)]);
                i++;
            }
            return crc;
        }
        #endregion

        #region 串口发送
        /// <summary>
        /// 串口发送
        /// </summary>
        /// <param name="bytelist"></param>
        public static void SendSerialPort(byte[] bytelist)
        {
            using (System.IO.Ports.SerialPort serial = new System.IO.Ports.SerialPort("COM3", 4800))
            {
                serial.Open();
                serial.Write(bytelist, 0, bytelist.Length);
                serial.Close();
            }
        }

        #endregion
    }

}
